/****************************************************************************
* copyright            : (C) 2009 William Viana Soares <vianasw@gmail.com>  *
*****************************************************************************/

/****************************************************************************
*                                                                           *
*   This program is free software; you can redistribute it and/or modify    *
*   it under the terms of the GNU General Public License as published by    *
*   the Free Software Foundation; either version 2 of the License, or       *
*   (at your option) any later version.                                     *
*                                                                           *
*****************************************************************************/

#include "point.h"
#include <sstream>

namespace ConciseQSR
{
    
/******* class Point *******************************************************************/
void Point::addRelation( BaseRelation rel, Reference refsys )
{
    map< Reference, set< BaseRelation > >::iterator rIt;
    rIt = m_relations.find( refsys );
    
    if( rIt != m_relations.end() )
    {
        rIt->second.insert( rel );        
    }
    else
    {
        set< BaseRelation > baseRelations;
        baseRelations.insert( rel );
        m_relations[ refsys ] = baseRelations;
    }
}


void Point::showRelations() const
{
    map< Reference, set< BaseRelation > >::const_iterator rIt;
    for( rIt = m_relations.begin(); rIt != m_relations.end(); rIt++ )
    {
        cout << "( " << m_label << " is ( ";
        for( set< BaseRelation >::const_iterator brIt = rIt->second.begin(); brIt != rIt->second.end(); brIt++ )
            cout << *brIt << " ";
        cout << ") " << "wrt R" << rIt->first  << " )" << endl;
    }
}

string Point::str() const
{
    stringstream out;
    out << "(" << m_label << " " << m_x << " " << m_y << ")";
    return out.str();
}

ostream& operator<<( ostream &os, const Point &p )
{
    os << "( " << p.m_label << " " << p.m_x << " " << p.m_y << " )";
    return os;
}


/*** class Reference  *****************************************************************/
Reference::Reference( Point a, Point b, bool isOpen )
    : m_pointA( a )
    , m_pointB( b )
    , m_isOpen( isOpen )
{
    m_points.insert( a.label() );
    m_points.insert( b.label() );
}

ostream& operator<<( ostream &os, const Reference &r )
{
    os << "( " << r.m_pointA.label() << " " << r.m_pointB.label() << " )";
    return os;
}

bool Reference::operator==( const Reference &other ) const
{
    return m_points == other.m_points;
}

bool Reference::operator<( const Reference & other ) const
{
    boost::hash< set< string > > hasher; 
    return hasher( m_points ) < hasher( other.m_points );
}

string Reference::str() const
{
    stringstream out;
    out << m_pointA.str() << m_pointB.str();
    return out.str();
}

}// namespace ConciseQSR